#include <iostream>
#include <CFGBuilder/CFGBuild.h>
#include <algorithm>
using namespace std;
using namespace sca;
int main(int argc,char *argv[]){

    std::string targetPath(argv[1]);
    sca::CFGBuilder builder(targetPath);
    builder.isTargetExist();
    builder.loadInstruction();
    builder.loadEntryAdds();
    builder.buildCallAndRetRelationship();
    builder.buildBasicBlocksVec();
    builder.createDependencies();
    // 打印每一个基本块
    for(int i = 0 ; i < builder.bbs.size(); i ++){
        shared_ptr<CFGBuilder::BasicBlock> bb = builder.bbs[i];
        cout << builder.bb2addr[bb] << endl;
        // 打印当前遍历的基本块的每一条指令
        for(int j = 0 ; j < bb->getNumOfInstructions() ; j++){
            std::cout << *bb->getInstruction(j) << std::endl;
        }

        cout << "-----------------------------------------------" << endl;
        // 打印每一个基本块的依赖关系
        for(int k = 0; k < bb->getNextBBs().size() ; k++){
            auto nextBB = bb->getNextBBs()[k];
            cout << "nextBB" << k+1 << "'s address = " << builder.bb2addr[nextBB] << endl;
            for(int s = 0 ; s < nextBB->getNumOfInstructions() ; s++){
                cout << *nextBB->getInstructions()[s] << endl;
            }
        }

        cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << endl;
    }
    cout << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << endl;
    for(auto iter = builder.beginAddr2Ret.begin();iter != builder.beginAddr2Ret.end();iter++){
        cout << iter->first << endl;
        for(auto inst: iter->second){
            cout << *inst << endl;
        }
        cout << "---------------------------" << endl;
    }

    cout << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << endl;
    for(auto iter = builder.retInst2CallInsts.begin() ; iter != builder.retInst2CallInsts.end() ; iter++){
        cout << *iter->first << endl;
        for(auto iter1 = iter->second.begin() ; iter1 != iter->second.end(); iter1++){
            cout << **iter1 << endl;
        }
    }
    return 0;
}